package com.dldata.devtools30.utils;

import org.apache.commons.lang.StringUtils;

import jakarta.servlet.http.HttpServletRequest;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;

/**
 * Created by 呵呵 on 2017-07-01.
 */
public class NetUtil {

    /**
     * @return
     */
    public static String getLoalIP() {
        try {
            Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
            while (interfaces.hasMoreElements()) {
                NetworkInterface current = interfaces.nextElement();
                if (!current.isUp() || current.isLoopback() || current.isVirtual()) continue;
                Enumeration<InetAddress> addresses = current.getInetAddresses();
                while (addresses.hasMoreElements()) {
                    InetAddress addr = addresses.nextElement();
                    if (addr.isLoopbackAddress()||addr instanceof Inet6Address) continue;

                    return addr.getHostAddress();
                }
            }
        } catch (SocketException e) {
            return "error: " + e.getLocalizedMessage();
        }
        return "error";
    }

    // 获取客户端IP
    public static String getRemoteIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
            //多次反向代理后会有多个ip值，第一个ip才是真实ip
            int index = ip.indexOf(",");
            if (index != -1) {
                ip = ip.substring(0, index);
                return ip.indexOf(":")>-1?ip.substring(0,ip.indexOf(":")):ip;
            } else {
                return ip.indexOf(":")>-1?ip.substring(0,ip.indexOf(":")):ip;
            }
        }
        ip = request.getHeader("X-Real-IP");
        if (StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
            return ip.indexOf(":")>-1?ip.substring(0,ip.indexOf(":")):ip;
        }
        ip = request.getHeader("Proxy-Client-IP");
        if (StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
            return ip.indexOf(":")>-1?ip.substring(0,ip.indexOf(":")):ip;
        }
        ip = request.getHeader("WL-Proxy-Client-IP");
        if (StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
            return ip.indexOf(":")>-1?ip.substring(0,ip.indexOf(":")):ip;
        }
        return request.getRemoteAddr();
    }

    /**
     * 获得外网IP
     * @return 外网IP
     */
    public static String getInternetIp() {
        try {
            Enumeration<NetworkInterface> networks = NetworkInterface.getNetworkInterfaces();
            while (networks.hasMoreElements()) {
                NetworkInterface networkInterface = networks.nextElement();

                if (!networkInterface.isUp() || networkInterface.isLoopback() || networkInterface.isVirtual()) continue;
                Enumeration<InetAddress> addrs = networkInterface.getInetAddresses();
                while (addrs.hasMoreElements()) {
                    InetAddress addr = addrs.nextElement();
                    if (addr.isLoopbackAddress()) continue;
                    if (!addr.isSiteLocalAddress()) {// 外网IP
                        return addr.getHostAddress();
                    }
                }
            }
            return "";
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取本机的内网ip地址
     * @return
     * @throws SocketException
     */
    public static String getInnetIp() throws SocketException {
          try {
            Enumeration<NetworkInterface> networks = NetworkInterface.getNetworkInterfaces();
            while (networks.hasMoreElements()) {
                NetworkInterface networkInterface = networks.nextElement();

                if (!networkInterface.isUp() || networkInterface.isLoopback() || networkInterface.isVirtual()) continue;
                Enumeration<InetAddress> addrs = networkInterface.getInetAddresses();
                while (addrs.hasMoreElements()) {
                    InetAddress addr = addrs.nextElement();
                    if (addr.isLoopbackAddress()) continue;
                    if (addr.isSiteLocalAddress()) {//内网IP
                        return addr.getHostAddress();
                    }
                }
            }
            return "";
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
       *  ip地址转成long型数字
       *  将IP地址转化成整数的方法如下：
       *  1、通过String的split方法按.分隔得到4个长度的数组
       *  2、通过左移位操作（<<）给每一段的数字加权，第一段的权为2的24次方，第二段的权为2的16次方，第三段的权为2的8次方，最后一段的权为1
       *  @param  strIp
       *  @return
       */
    public static long  ipToLong(String  strIp)  {
        String[]ip  =  strIp.split("\\.");
        return  (Long.parseLong(ip[0])  <<  24)  +  (Long.parseLong(ip[1])  <<  16)  +  (Long.parseLong(ip[2])  <<  8)  +  Long.parseLong(ip[3]);
    }

    /**
       *  将十进制整数形式转换成127.0.0.1形式的ip地址
       *  将整数形式的IP地址转化成字符串的方法如下：
       *  1、将整数值进行右移位操作（>>>），右移24位，右移时高位补0，得到的数字即为第一段IP。
       *  2、通过与操作符（&）将整数值的高8位设为0，再右移16位，得到的数字即为第二段IP。
       *  3、通过与操作符吧整数值的高16位设为0，再右移8位，得到的数字即为第三段IP。
       *  4、通过与操作符吧整数值的高24位设为0，得到的数字即为第四段IP。
       *  @param  longIp
       *  @return
       */
    public  static  String  longToIP(long  longIp)  {
        StringBuffer  sb  =  new  StringBuffer("");
        //  直接右移24位
        sb.append(String.valueOf((longIp  >>>  24)));
        sb.append(".");
        //  将高8位置0，然后右移16位
        sb.append(String.valueOf((longIp  &  0x00FFFFFF)  >>>  16));
        sb.append(".");
        //  将高16位置0，然后右移8位
        sb.append(String.valueOf((longIp  &  0x0000FFFF)  >>>  8));
        sb.append(".");
        //  将高24位置0
        sb.append(String.valueOf((longIp  &  0x000000FF)));
        return  sb.toString();
    }

    public  static  void  main(String[]  args)  {
        System.out.println(ipToLong("219.239.110.138"));
        System.out.println(longToIP(18537472));
    }
}
